From 8b0d443af05a1bf27267de2170f756908de06bf3 Mon Sep 17 00:00:00 2001 From: robertl Date: Fri, 19 May 2006 23:10:58 +0000 Subject: [PATCH] Add Franson's GPS Simulator. git-svn-id: http://gpsbabel.googlecode.com/svn/trunk@2110 f51c46e8-681c-474f-0cfe-069cfd0219fb --- gpsbabel/gpssim.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 gpsbabel/gpssim.c diff --git a/gpsbabel/gpssim.c b/gpsbabel/gpssim.c new file mode 100644 index 000000000..f9c66fa87 --- /dev/null +++ b/gpsbabel/gpssim.c @@ -0,0 +1,207 @@ +/* + Write points to Franson Technology GpsGate simulator + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" + +#define MYNAME "gpssim" + +static FILE *fout; +static char *wayptspd; +static char *splitfiles_opt; +static int splitfiles; +static char *fnamestr; +static int trk_count; +static int doing_tracks; + +static +arglist_t gpssim_args[] = { + { "wayptspd", &wayptspd, "Default speed for waypoints (knots/hr)", + NULL, ARGTYPE_FLOAT, ARG_NOMINMAX }, + { "split", &splitfiles_opt, "Split input into separate files", + "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +/* + * The only thing kind of odd about this format is the "split" + * option. There's some trashing about with the 'splitfiles' toggle + * to ensure that waypoints land in one file and each track and each + * route land in files of their own. + */ + +static void +gpssim_wr_init(const char *fname) +{ + fnamestr = xstrdup(fname); + trk_count = 0; + splitfiles = splitfiles_opt ? atoi(splitfiles_opt) : 0; + + /* If writing to stdout, never split files */ + if (0 == strcmp("-",splitfiles_opt)) { + splitfiles = 0; + } + + if (!splitfiles) { + fout = xfopen(fname, "wb", MYNAME); + } +} + +static void +gpssim_wr_deinit(void) +{ + if (fout) { + fclose(fout); + fout = NULL; + } + + xfree(fnamestr); +} + + +/* + * All these files are written in binary mode, so put CR/NL pairs + * in them explictly in case we're writing from a UNIX-like host. + */ + +static void +gpssim_write_sentence(const char *const s) +{ + int cksum; + fprintf(fout, "$%s*%02X\r\n", s, nmea_cksum(s)); +} + +static void +gpssim_write_spd(double knotsperhour) +{ + char obuf[1024]; + + snprintf(obuf, sizeof(obuf), "FRSPD,%.2f", knotsperhour); + gpssim_write_sentence(obuf); +} + +#define mpsec2knots(n) ((n) * 1.9438445 / 0.51444444) + +static void +gpssim_write_pt(const waypoint *wpt) +{ + char obuf[1024]; + double lat, lon; + + if (wpt->speed > 0) { + gpssim_write_spd(mpsec2knots(wpt->speed)); + } + + lat = degrees2ddmm(wpt->latitude); + lon = degrees2ddmm(wpt->longitude); + + snprintf(obuf, sizeof(obuf), "FRWPT,%10.5f,%c,%011.5f,%c,%.1f", + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', + wpt->altitude == unknown_alt ? 0 : wpt->altitude + ); + + if ( wpt->creation_time ) { + char tbuf[20]; + int hms, ymd; + struct tm *tm; + + tm = gmtime(&wpt->creation_time); + hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec; + ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year; + snprintf(tbuf, sizeof(tbuf), ",%d,%d",ymd, hms); + strcat(obuf, tbuf); + } + + gpssim_write_sentence(obuf); +} + +static void +gpssim_trk_hdr(const route_head *rh) +{ + if (splitfiles) { + char c[1024]; + char *ofname = xstrdup(fnamestr); + + if (fout) { + fatal(MYNAME, ": output file already open.\n"); + } + + snprintf(c, sizeof(c), "%s%04d.gpssim", + doing_tracks ? "-track" : "-route", + trk_count++); + ofname = xstrappend(ofname, c); + fout = xfopen(ofname, "wb", MYNAME); + xfree(ofname); + } + track_recompute(rh, NULL); +} + +static void +gpssim_trk_ftr(const route_head *rh) +{ + if (splitfiles) { + fclose(fout); + fout = NULL; + } +} + +static void +gpssim_write(void) +{ + if (waypt_count()) { + if (splitfiles) { + char *ofname = xstrdup(fnamestr); + ofname = xstrappend(ofname, "-waypoints.gpssim"); + fout = xfopen(ofname, "wb", MYNAME); + xfree(ofname); + } + if (wayptspd && wayptspd[0]) { + gpssim_write_spd(atof(wayptspd)); + } + waypt_disp_all(gpssim_write_pt); + if (splitfiles) { + fclose(fout); + fout = NULL; + } + } + + doing_tracks = 1; + track_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); + + trk_count = 0; + doing_tracks = 0; + route_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); +} + + +ff_vecs_t gpssim_vecs = { + ff_type_file, + { ff_cap_write, ff_cap_write, ff_cap_write }, + NULL, + gpssim_wr_init, + NULL, + gpssim_wr_deinit, + NULL, + gpssim_write, + NULL, + gpssim_args, + CET_CHARSET_ASCII, 0 +}; -- 2.30.2